package com.business.java2cache.memcache;

import com.business.java2cache.core.Cache;
import com.business.java2cache.core.Java2Cache;
import com.business.java2cache.util.CacheException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

/**
 */
public class MemCache implements Cache {
    private static MemCacheOptUtils memCacheOptUtils = null;

    private static MemCache memCache = new MemCache();

    public static MemCache getInstance() {
        return memCache;
    }

    private MemCache() {
        memCacheOptUtils = MemCacheOptUtils.getInstance();
    }


    private final static Logger log = LoggerFactory.getLogger(MemCache.class);

    /**
     * 在region里增加一个可选的层级,作为命名空间,使结构更加清晰
     * 同时满足小型应用,多个Java2Cache共享一个memcache database的场景
     *
     * @param region
     * @param key    都不为空时：namespace:region:key
     *               只有key时，namespace:key
     * @return
     */
    private String getKeyName(String region, String key) {
        String nameSpace = Java2Cache.getConfig().getProperty("redis.namespace");
        String obj;
        if (nameSpace != null && !nameSpace.isEmpty()) {
            if (region != null && !region.isEmpty()) {
                region = nameSpace + ":" + region;
                obj = region + ":" + key;
            } else {
                obj = nameSpace + ":" + key;
            }
        } else {
            if (region != null && !region.isEmpty()) {
                obj = region + ":" + key;
            } else {
                obj = key;
            }
        }
        return obj;
    }

    /**
     * Get an item from the cache, nontransactionally
     *
     * @param region cache region
     * @param key    cache key
     * @return the cached object or null
     */
    @Override
    public Object get(String region, String key) throws CacheException {
        String _key = getKeyName(region, key);
        return memCacheOptUtils.get(_key);
    }

    /**
     * Add an item to the cache, nontransactionally, with
     * failfast semantics
     *
     * @param region
     * @param key     cache key
     * @param value   cache value
     * @param seconds cache Expiration time
     */
    @Override
    public void set(String region, String key, Object value, int seconds) throws CacheException {
        if (value == null)//vaule==null delete
            remove(region, key);
        else {
            String _key = getKeyName(region, key);
            memCacheOptUtils.set(_key, value, seconds);
        }

    }

    /**
     * @param key Cache key
     *            Remove an item from the cache
     */
    @Override
    public void remove(String region, Object key) throws CacheException {
        if (key instanceof List) {
            List<String> keys = (List<String>) key;
            for (String key2 : keys) {
                String _key = getKeyName(region, key2.toString());
                memCacheOptUtils.remove(_key);
            }
        } else {
            String _key = getKeyName(region, key.toString());
            memCacheOptUtils.remove(_key);
        }
    }

    /**
     * Clear the cache
     */
    @Override
    public void clear(String region) throws CacheException {
        //memCacheOptUtils.getMemcachedClient().flush();
    }

    /**
     * update exprie time
     *
     * @param key
     * @param seconds
     */
    @Override
    public Object exprie(String region, String key, int seconds) {
        String _key = getKeyName(region, key);
        return memCacheOptUtils.getAndTouch(_key, seconds);
    }
}
